// **********************************************************************
//
// Copyright (c) 2003-2010 ZeroC, Inc. All rights reserved.
//
// This copy of Ice is licensed to you under the terms described in the
// ICE_LICENSE file included in this distribution.
//
// **********************************************************************
package IceSSL;
final class AcceptorI implements IceInternal.Acceptor
{
public java.nio.channels.ServerSocketChannel
fd()
{
return _fd;
}
public void
close()
{
if(_instance.networkTraceLevel() >= 1)
{
String s = "stopping to accept ssl connections at " + toString();
_logger.trace(_instance.networkTraceCategory(), s);
}
assert(_fd != null);
IceInternal.Network.closeSocketNoThrow(_fd);
_fd = null;
}
public void
listen()
{
// Nothing to do.
if(_instance.networkTraceLevel() >= 1)
{
StringBuffer s = new StringBuffer("accepting ssl connections at ");
s.append(toString());
java.util.List<String> interfaces =
IceInternal.Network.getHostsForEndpointExpand(_addr.getAddress().getHostAddress(),
_instance.protocolSupport(), true);
if(!interfaces.isEmpty())
{
s.append("\nlocal interfaces: ");
s.append(IceUtilInternal.StringUtil.joinString(interfaces, ", "));
}
_logger.trace(_instance.networkTraceCategory(), s.toString());
}
}
public IceInternal.Transceiver
accept()
{
//
// The plug-in may not be fully initialized.
//
if(!_instance.initialized())
{
Ice.PluginInitializationException ex = new Ice.PluginInitializationException();
ex.reason = "IceSSL: plug-in is not initialized";
throw ex;
}
java.nio.channels.SocketChannel fd = IceInternal.Network.doAccept(_fd);
javax.net.ssl.SSLEngine engine = null;
try
{
IceInternal.Network.setBlock(fd, false);
IceInternal.Network.setTcpBufSize(fd, _instance.communicator().getProperties(), _logger);
engine = _instance.createSSLEngine(true);
}
catch(RuntimeException ex)
{
IceInternal.Network.closeSocketNoThrow(fd);
throw ex;
}
if(_instance.networkTraceLevel() >= 1)
{
_logger.trace(_instance.networkTraceCategory(), "accepting ssl connection\n" +
IceInternal.Network.fdToString(fd));
}
return new TransceiverI(_instance, engine, fd, "", true, true, _adapterName);
}
public String
toString()
{
return IceInternal.Network.addrToString(_addr);
}
int
effectivePort()
{
return _addr.getPort();
}
AcceptorI(Instance instance, String adapterName, String host, int port)
{
_instance = instance;
_adapterName = adapterName;
_logger = instance.communicator().getLogger();
_backlog = instance.communicator().getProperties().getPropertyAsIntWithDefault("Ice.TCP.Backlog", 511);
try
{
_fd = IceInternal.Network.createTcpServerSocket();
IceInternal.Network.setBlock(_fd, false);
IceInternal.Network.setTcpBufSize(_fd, _instance.communicator().getProperties(), _logger);
if(!System.getProperty("os.name").startsWith("Windows"))
{
//
// Enable SO_REUSEADDR on Unix platforms to allow
// re-using the socket even if it's in the TIME_WAIT
// state. On Windows, this doesn't appear to be
// necessary and enabling SO_REUSEADDR would actually
// not be a good thing since it allows a second
// process to bind to an address even it's already
// bound by another process.
//
// TODO: using SO_EXCLUSIVEADDRUSE on Windows would
// probably be better but it's only supported by recent
// Windows versions (XP SP2, Windows Server 2003).
//
IceInternal.Network.setReuseAddress(_fd, true);
}
_addr = IceInternal.Network.getAddressForServer(host, port, _instance.protocolSupport());
if(_instance.networkTraceLevel() >= 2)
{
String s = "attempting to bind to ssl socket " + toString();
_logger.trace(_instance.networkTraceCategory(), s);
}
_addr = IceInternal.Network.doBind(_fd, _addr, _backlog);
}
catch(RuntimeException ex)
{
_fd = null;
throw ex;
}
}
protected synchronized void
finalize()
throws Throwable
{
IceUtilInternal.Assert.FinalizerAssert(_fd == null);
super.finalize();
}
private Instance _instance;
private String _adapterName;
private Ice.Logger _logger;
private java.nio.channels.ServerSocketChannel _fd;
private int _backlog;
private java.net.InetSocketAddress _addr;
}